package com.ip.controller.open;

import com.alibaba.fastjson.JSONObject;
import com.ip.pojo.common.ResponseEntity;
import com.ip.pojo.common.UserInfoVO;
import com.ip.pojo.enums.ResponseCodeEnum;
import com.ip.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;


@RestController
@RequestMapping("/wx")
public class WeiChartController {
    private static final Logger logger = LoggerFactory.getLogger(WeiChartController.class);

    /** 微信配置 */
    @Value("${spring.wei-chart.app-id}")
    private String appId;
    @Value("${spring.wei-chart.app-secret}")
    private String appSecret;
    @Value("${domain.url}")
    private String domainUrl;
    @Value("${spring.wei-chart.token}")
    private String token;
    @Value("${session.timeout}")
    private Integer sessionTimeout;

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserService userService;

    /**
     * 获取微信二维码 URL
     * @return
     */
    @GetMapping("/authUrl")
    public ResponseEntity<String> authUrl() {
        String redirectUri = URLEncoder.encode(domainUrl + "/wx/callback", StandardCharsets.UTF_8);
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
                "appid=" + appId +
                "&redirect_uri=" + redirectUri +
                "&response_type=code" +
                "&scope=snsapi_userinfo" +
                "&state=STATE#wechat_redirect";
        return ResponseEntity.success(url);
    }

    @GetMapping("/userInfo/{code}")
    public ResponseEntity<UserInfoVO> obtainUserInfo(@RequestParam("code") String code) {
        return ResponseEntity.success((UserInfoVO) redisTemplate.boundValueOps(code).get());
    }

    /**
     * 微信回调接口
     * @param code
     * @return
     * @throws IOException
     */
    @GetMapping("/callback")
    public ResponseEntity<UserInfoVO> callback(@RequestParam("code") String code, HttpSession session) {
        logger.info("登录请求：{}", code);
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=" + appId +
                "&secret=" + appSecret +
                "&code=" + code +
                "&grant_type=authorization_code";
        String jsonToken = restTemplate.getForObject(url, String.class);
        if (!JSONObject.isValidObject(jsonToken)) {
            logger.error("weiChart token is invalid, tokenJson={}", jsonToken);
            return ResponseEntity.failed(ResponseCodeEnum.LOGIN_TOKEN_FAILED);
        }
        JSONObject tokenJson = JSONObject.parseObject(jsonToken);
        String accessToken = tokenJson.getString("access_token");
        String openid = tokenJson.getString("openid");
        if (StringUtils.isBlank(accessToken) || StringUtils.isBlank(openid)) {
            logger.error("weiChart token query failed, tokenJson={}", tokenJson);
            return ResponseEntity.failed(ResponseCodeEnum.LOGIN_TOKEN_FAILED);
        }
        // 查询用户信息
        String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?" +
                "access_token=" + accessToken +
                "&openid=" + openid +
                "&lang=zh_CN";
        String userInfoRs = restTemplate.getForObject(userInfoUrl, String.class);
        if (!JSONObject.isValidObject(userInfoRs)) {
            logger.error("weiChart user info query failed, user info json is invalid, userInfoRs={}", userInfoRs);
            return ResponseEntity.failed(ResponseCodeEnum.LOGIN_TOKEN_FAILED);
        }
        JSONObject userJson = JSONObject.parseObject(userInfoRs);
        String nickname = userJson.getString("nickname");
        String headImgUrl = userJson.getString("headimgurl");
        // 记录扫码登录成功的用户
        UserInfoVO userInfo = new UserInfoVO();
        userInfo.setOpenId(openid);
        userInfo.setUserName(nickname);
        userInfo.setHeadImgUrl(headImgUrl);
        // 数据放入缓存和 session
        redisTemplate.boundValueOps(code).set(userInfo, sessionTimeout, TimeUnit.HOURS);
        // 保存用户信息
        userService.saveUserInfo(openid, nickname, headImgUrl);
        return ResponseEntity.success(userInfo);
    }

    /**
     * 微信登录接入-接口配置信息接口
     * @param request
     * @param response
     */
    @GetMapping(value = "/check")
    public void check(HttpServletRequest request,
                      HttpServletResponse response){
        logger.info("auth checking start...");
        try {
            String nonce = request.getParameter("nonce");
            String timestamp = request.getParameter("timestamp");
            String signature = request.getParameter("signature");
            String echoStr = request.getParameter("echostr");
            logger.info("auth,nonce:{},timestamp:{},signature:{},echoStr:{}",nonce,timestamp,signature,echoStr);
            response.setContentType("text/html");
            response.getWriter().print(echoStr);
            logger.info("auth echoStr:"+echoStr);
            logger.info("auth checking success!");
        } catch (Exception e) {
            logger.error("wxLoginError-check:" + e.getMessage(), e);
        }
    }
}
